/*
 * Revision Control Information
 *
 * /projects/hsis/CVS/utilities/list/list.h,v
 * shiple
 * 1.5
 * 1995/08/30 17:37:15
 *
 */
/*
 * List Management Package Header File
 *
 * David Harrison
 * University of California, 1985
 *
 * This file contains public type definitions for the List Managment
 * package implemented in list.c.  This is stand alone package.
 */

#ifndef LS_DEFINED
#define LS_DEFINED

/* This can be typedef'ed to void if supported */
typedef struct ls_dummy_defn {
    int dummy;			/* Not used */
} ls_dummy;

typedef ls_dummy *lsList;	/* List handle           */
typedef ls_dummy *lsGen;	/* List generator handle */
typedef ls_dummy *lsHandle;	/* Handle to an item     */
typedef int lsStatus;		/* Return codes          */
typedef char *lsGeneric;	/* Generic pointer       */

#define	LS_NIL		0	/* Nil for lsList       */

#define LS_BADSTATE	-3	/* Bad generator state   */
#define LS_BADPARAM	-2	/* Bad parameter value   */
#define LS_NOMORE	-1	/* No more items         */

#define	LS_OK		0

#define LS_BEFORE	1	/* Set spot before object */
#define LS_AFTER	2	/* Set spot after object  */
#define LS_STOP		3	/* Stop generating items  */
#define LS_DELETE	4	/* Delete generated item  */

/*
 * For all those routines that take a handle,  this macro can be
 * used when no handle is required.
 */

#define LS_NH		(lsHandle *) 0

typedef lsGeneric (*LS_PFLSG)();

/*
 * Used for LS_PFLSG to copy a list
 */
#define LS_COPY         (LS_PFLSG) (-1)

EXTERN lsList lsCreate ARGS((void));
  /* Create a new list */
EXTERN lsList lsSingleton ARGS((lsGeneric, lsHandle *));
  /* Create a new list containing one element */
EXTERN lsStatus lsDestroy ARGS((lsList, void (*)()));
  /* Delete a previously created list */
EXTERN lsStatus lsDestroyListList ARGS((lsList));
  /* Delete a previously created list of lists of ground */
EXTERN lsList lsCopy ARGS((lsList, LS_PFLSG));
  /* Copies the contents of a list    */
EXTERN lsList lsCopyListList ARGS((lsList));
  /* Copies the contents of a list of lists of ground  */
EXTERN lsList lsAppend ARGS((lsList, lsList, LS_PFLSG));
  /* Append two lists */
EXTERN void lsJoin ARGS((lsList, lsList, LS_PFLSG));
  /* Append second list to first list */

EXTERN lsStatus lsFirstItem ARGS((lsList, lsGeneric *, lsHandle *));
  /* Gets the first item of a list */
EXTERN lsStatus lsLastItem ARGS((lsList, lsGeneric *, lsHandle *));
  /* Gets the last item of a list */

EXTERN lsStatus lsNewBegin ARGS((lsList, lsGeneric, lsHandle *));
  /* Add item to start of list */
EXTERN lsStatus lsNewEnd ARGS((lsList, lsGeneric, lsHandle *));
  /* Add item to end of list */

EXTERN lsStatus lsDelBegin ARGS((lsList, lsGeneric *));
  /* Delete first item of a list */
EXTERN lsStatus lsDelEnd ARGS((lsList, lsGeneric *));
  /* Delete last item of a list */

EXTERN int lsLength ARGS((lsList));
  /* Returns the length of the list */

EXTERN lsGen lsStart ARGS((lsList));
  /* Begin generation of items in a list */
EXTERN lsGen lsEnd ARGS((lsList));
  /* Begin generation at end of list */
EXTERN lsGen lsGenHandle ARGS((lsHandle, lsGeneric *, int));
  /* Produces a generator given a handle */
EXTERN lsStatus lsNext ARGS((lsGen, lsGeneric *, lsHandle *));
  /* Generate next item in sequence */
EXTERN lsStatus lsPrev ARGS((lsGen, lsGeneric *, lsHandle *));
  /* Generate previous item in sequence */
EXTERN lsStatus lsInBefore ARGS((lsGen, lsGeneric, lsHandle *));
  /* Insert an item before the most recently generated by lsNext */
EXTERN lsStatus lsInAfter ARGS((lsGen, lsGeneric, lsHandle *));
  /* Insert an item after the most recently generated by lsNext  */
EXTERN lsStatus lsDelBefore ARGS((lsGen, lsGeneric *));
  /* Delete the item before the current spot */
EXTERN lsStatus lsDelAfter ARGS((lsGen, lsGeneric *));
  /* Delete the item after the current spot */
EXTERN lsStatus lsFinish ARGS((lsGen));
  /* End generation of items in a list */

EXTERN lsList lsQueryHandle ARGS((lsHandle));
  /* Returns the list of a handle */
EXTERN lsGeneric lsFetchHandle ARGS((lsHandle));
  /* Returns data associated with handle */
EXTERN lsStatus lsRemoveItem ARGS((lsHandle, lsGeneric *));
  /* Removes item associated with handle from list */

EXTERN lsStatus lsSort ARGS((lsList, int (*)()));

  /* Sorts a list */
EXTERN lsStatus lsUniq ARGS((lsList, int (*)(), void (*)() ));
  /* Removes duplicates from a sorted list */
/*
 * Macro to iterate the items of a list.Note the following:
 * 1) in a for loop, the test is evaluate before the first time through the body
 * 2) the logical OR operator guarantees left to right evaluation, and the second
 *    operand is not evaluated if first operand evaluates to non-zero
 * 3) the comma operator returns the value of its second argument.
 */
#define lsForEachItem(                                         \
  list,  /* lsList, list to iterate */                         \
  gen,   /* lsGen, local variable for iterator */              \
  data   /* lsGeneric, variable to return data */              \
)				                               \
  for(gen = lsStart(list); 				       \
      (lsNext(gen, (lsGeneric *) &data, LS_NH) == LS_OK)       \
      || ((void) lsFinish(gen), 0);                            \
      )


#endif
